package com.hsd.znsh.service.impl;

import com.hsd.znsh.converter.SensorConverter;
import com.hsd.znsh.entity.*;
import com.hsd.znsh.enums.DeletedStatusEnum;
import com.hsd.znsh.enums.OnlineStatusEnum;
import com.hsd.znsh.enums.ResultEnum;
import com.hsd.znsh.exception.ZnshException;
import com.hsd.znsh.pojo.output.SensorVO;
import com.hsd.znsh.pojo.query.SensorInfoQuery;
import com.hsd.znsh.pojo.query.SensorQuery;
import com.hsd.znsh.repository.*;
import com.hsd.znsh.service.LoraService;
import com.hsd.znsh.service.SensorService;
import com.hsd.znsh.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalField;
import java.util.*;

/*
 * @auther: wangjiacai
 *
 * @create: 2018-04-25 14:48:27
 */
@Service
public class SensorServiceImpl extends BaseServiceImpl implements SensorService {

    @Autowired
    private SensorRepository sensorRepository;

    @Autowired
    private SensorTypeRepository sensorTypeRepository;

    @Autowired
    private SensorDataRepository sensorDataRepository;

    @Autowired
    private HostRepository hostRepository;

    @Autowired
    private HostManagerRepository hostManagerRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PropertyRepository propertyRepository;

    @Autowired
    private SensorTypePropertyRepository sensorTypePropertyRepository;

    @Autowired
    private LoraService loraService;

    @Override
    public long getSensorListTotalPages(SensorQuery sensorQuery,Integer userId) {
        if(userId!=null) sensorQuery.setCreateUserId(userId);
        return this.count(HqlUtil.getCountHql(sensorQuery),sensorQuery);
    }

    @Override
    public List<SensorVO> getSensorList(SensorQuery sensorQuery, Pageable pageable,Integer userId) {
        if(userId!=null) sensorQuery.setCreateUserId(userId);
        List<Sensor> list=this.find(HqlUtil.getQueryHql(sensorQuery),sensorQuery);
        return SensorConverter.converterToSensorVOList(list,hostRepository,userRepository,sensorTypeRepository);
    }

    @Override
    public SensorVO getSensorInfo(Integer id) {
        Sensor sensor=sensorRepository.findOne(id);
        return SensorConverter.converterToSensorVO(sensor,hostRepository,userRepository,sensorTypeRepository);
    }

    @Override
    public SensorVO getSensorInfoBySensorSn(String sensorSn) {
        Sensor sensor=sensorRepository.findBySensorSn(sensorSn);
        return SensorConverter.converterToSensorVO(sensor,hostRepository,userRepository,sensorTypeRepository);
    }

    @Override
    public Sensor addSensor(Sensor sensor) {
        if(!loraService.addDevice(sensor)) throw new ZnshException("添加失败，请重新添加");
        if(SecurityUtil.hasRole("ROLE_ROOT")){
            if(sensor.getCreateUserId()==null){
                sensor.setCreateUserId(SecurityUtil.getUserId());
            }
        }else{
            sensor.setCreateUserId(SecurityUtil.getUserId());
        }
        return sensorRepository.save(sensor);
    }

    @Override
    public Sensor addSensorByAppUser(Sensor sensor, User user) {
        /*if(sensorRepository.findByFogId(sensor.getFogId())!=null){
            throw new ZnshException(ResultEnum.FOGID_ERROR);
        }*/
        loraService.addDevice(sensor);
        sensor.setCreateUserId(user.getCreateUserId());
        sensor.setOnlineStatus(OnlineStatusEnum.NOT_ONLINE.getCode());
        return sensorRepository.save(sensor);
    }

    @Override
    public Sensor updateSensor(Sensor sensor) {
        if(SecurityUtil.hasRole("ROLE_ROOT")){
            if(sensor.getCreateUserId()==null){
                sensor.setCreateUserId(SecurityUtil.getUserId());
            }
        }else{
            sensor.setCreateUserId(SecurityUtil.getUserId());
        }
        Sensor object=sensorRepository.findOne(sensor.getId());
        BeanUtil.copyPropertiesIgnoreNull(sensor,object);
        return sensorRepository.save(object);
    }

    @Override
    public Sensor   updateSensorByAppUser(Sensor sensor, User user) {
        sensor.setCreateUserId(user.getCreateUserId());
        Sensor object=sensorRepository.findOne(sensor.getId());
        Sensor object2=sensorRepository.findOne(sensor.getId());
        BeanUtil.copyPropertiesIgnoreNull(sensor,object);
        return object2;
    }

    @Override
    public Sensor
    deleteSensor(Integer id) {
        Sensor sensor=sensorRepository.findOne(id);
        loraService.deleteDevice(sensor.getSensorSn());
        sensorRepository.delete(id);
        return sensor;
    }

    @Override
    public Sensor deleteSensor(String sensorSn) {
        if (!loraService.deleteDevice(sensorSn)) throw new ZnshException("删除失败，请重新删除");
        Sensor sensor = sensorRepository.findBySensorSn(sensorSn);
        sensorRepository.delete(sensor);
        return sensor;
    }

    @Override
    public Map<String,Object> getSensorAverageValueByHostSn(String hostSn,Integer sensorTypeId,Integer bh) {
        SensorTypeProperty sensorTypeProperty=sensorTypePropertyRepository.findBySensorTypeIdAndBh(
                sensorTypeId,bh);
        Property property=propertyRepository.findOne(sensorTypeProperty.getPropertyId());
        Map<String,Object> map=BeanUtil.objectToMap(property);
        Host host=hostRepository.findByHostSn(hostSn);
        List<Sensor> sensorList=sensorRepository.findByHostIdAndSensorTypeId(host.getId(),sensorTypeId);
        Double value=0.0;
        for(Sensor sensor:sensorList){
            SensorData sensorData=sensorDataRepository.findBySensorSnAndTimeAndPropertyId(
                    sensor.getSensorSn(),sensor.getTime(),property.getId());
            if(sensorData!=null) value+=sensorData.getValue();
        }
        if(sensorList==null||sensorList.size()==0)  map.put("value",0.0);
        else map.put("value",value/sensorList.size());
        return map;
    }

    @Override
    public List<Sensor> getSensorListByHostSn(String hostSn) {
        Host host=hostRepository.findByHostSn(hostSn);
        return sensorRepository.findByHostId(host.getId());
    }

    @Override
    public SensorType getSensorTypeBySensorSn(String sensorSn) {
        Sensor sensor=sensorRepository.findBySensorSn(sensorSn);
        return sensorTypeRepository.findOne(sensor.getSensorTypeId());
    }

    @Override
    public List<Sensor> getSensorListByAppUser(User user) {
        List<Integer> list=hostRepository.findIdListByManagerId(user.getCreateUserId());
        list.addAll(hostManagerRepository.findBySecondManagerId(user.getId()));
        return sensorRepository.findByHostIdIn(list);
    }
}
